package org.mybatis.generator.plugins;

import java.util.List;
import java.util.Properties;
import java.util.Random;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.TopLevelClass;

/**
 * <b><code>OverWriteXmlPlugin</code></b>
 * <p/>
 * Description: 覆盖旧的XML插件
 * <p/>
 * <b>Creation Time:</b> 2018/02/23.
 */
public class MySerializablePlugin extends PluginAdapter {

	private FullyQualifiedJavaType serializable; // 对应java.io.Serializable的java类型
	private FullyQualifiedJavaType gwtSerializable; // 对应com.google.gwt.user.client.rpc.IsSerializable的java类型
	private boolean addGWTInterface; // 是否实现com.google.gwt.user.client.rpc.IsSerializable接口
	private boolean suppressJavaInterface; // 是否实现java.io.Serializable接口

	public MySerializablePlugin() {
		super();
		serializable = new FullyQualifiedJavaType("java.io.Serializable"); //$NON-NLS-1$ 实例化
		gwtSerializable = new FullyQualifiedJavaType("com.google.gwt.user.client.rpc.IsSerializable"); //$NON-NLS-1$ 实例化
	}

	@Override
	public boolean validate(List<String> warnings) {
		// this plugin is always valid
		return true;
	}

	@Override
	public void setProperties(Properties properties) {
		super.setProperties(properties);
		addGWTInterface = Boolean.valueOf(properties.getProperty("addGWTInterface")); //$NON-NLS-1$
		suppressJavaInterface = Boolean.valueOf(properties.getProperty("suppressJavaInterface")); //$NON-NLS-1$
	}

	@Override
	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		makeSerializable(topLevelClass, introspectedTable);
		return true;
	}

	@Override
	public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		makeSerializable(topLevelClass, introspectedTable);
		return true;
	}

	@Override
	public boolean modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable) {
		makeSerializable(topLevelClass, introspectedTable);
		return true;
	}

	protected void makeSerializable(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		if (addGWTInterface) { // 是否要实现com.google.gwt.user.client.rpc.IsSerializable接口
			topLevelClass.addImportedType(gwtSerializable); // import com.google.gwt.user.client.rpc.IsSerializable;
			topLevelClass.addSuperInterface(gwtSerializable);// 实现接口
		}

		if (!suppressJavaInterface) { // 不禁止实现java.io.Serializable
			topLevelClass.addImportedType(serializable); // import java.io.Serializable;
			topLevelClass.addSuperInterface(serializable); // 实现java.io.Serializable接口

			// 添加serialVersionUID字段
			// 最终生成代码private static final long serialVersionUID = 1L;
			Field field = new Field();
			field.setFinal(true); // 添加final修饰
			field.setInitializationString(new Random().nextLong() + "L"); //$NON-NLS-1$ 赋值为1L
			field.setName("serialVersionUID"); //$NON-NLS-1$ 设置字段名称为serialVersionUID
			field.setStatic(true); // 添加static关键字
			field.setType(new FullyQualifiedJavaType("long")); //$NON-NLS-1$ 声明类型
			field.setVisibility(JavaVisibility.PRIVATE); // 声明为私有
			context.getCommentGenerator().addFieldComment(field, introspectedTable); // 生成注解

			// 把拼装好的方法DOM添加到topLevelClass中，完成接口的实现和字段的添加
			topLevelClass.addField(field);
		}
	}

}
